import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.UnsupportedEncodingException;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.List;


public class FileUtilities {
    static public LineNumberReader openFile(File file)
            throws UnsupportedEncodingException, FileNotFoundException {
        return new LineNumberReader(
            new InputStreamReader(new FileInputStream(file), "UTF-8"));
    }
    
    static public List<String> nextRow(LineNumberReader reader, char separator) throws IOException {
        String line = reader.readLine();
        if (line == null) {
            return null;
        }
        
        List<String> row = new ArrayList<String>();
        int start = 0;
        while (line != null && start < line.length()) {
            char c = line.charAt(start);
            if (c != '"') {
                int separatorIndex = line.indexOf(separator, start);
                if (separatorIndex < start) {
                    row.add(line.substring(start));
                    break;
                } else {
                    row.add(line.substring(start, separatorIndex));
                    start = separatorIndex + 1;
                }
            } else {
                StringBuffer sb = new StringBuffer();
                int start2 = start + 1;
                while (line != null && start2 < line.length()) {
                    int quote = line.indexOf('"', start2);
                    if (quote < 0) {
                        // The quoted cell runs over a line break
                        sb.append(line.substring(start));
                        line = reader.readLine();
                        start = start2 = 0;
                    } else {
                        if (quote < line.length() - 1 && line.charAt(quote + 1) == '"') {
                            start2 = quote + 2;
                        } else {
                            start2++;
                            break;
                        }
                    }
                }
                
                if (line != null) {
                    sb.append(line.substring(start, start2));
                }
                row.add(sb.toString());
                
                start = start2 + 1; // skip separator
            }
        }
        return row;
    }

    static public void copyFile(File source, File target) throws IOException {
        FileChannel in = new FileInputStream(source).getChannel();
        FileChannel out = new FileOutputStream(target).getChannel();

        in.transferTo(0, in.size(), out);

        in.close();
        out.close();
    }
}
